home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / game / shoot / ADescentSrc.lha / descent / main / bmread.c < prev    next >
C/C++ Source or Header  |  1998-08-08  |  60KB  |  2,017 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: /usr/CVS/descent/main/bmread.c,v $
  15.  * $Revision: 1.2 $
  16.  * $Author: nobody $
  17.  * $Date: 1998/08/08 15:42:19 $
  18.  * 
  19.  * Routines to parse bitmaps.tbl
  20.  * 
  21.  * $Log: bmread.c,v $
  22.  * Revision 1.2  1998/08/08 15:42:19  nobody
  23.  * Activated the Editior
  24.  *
  25.  * Revision 1.1.1.1  1998/03/03 15:12:12  nobody
  26.  * reimport after crash from backup
  27.  *
  28.  * Revision 1.1.1.1  1998/02/13  20:20:43  hfrieden
  29.  * Initial Import
  30.  *
  31.  * Revision 2.4  1995/03/28  18:05:29  john
  32.  * Fixed it so you don't have to delete pig after changing bitmaps.tbl
  33.  * 
  34.  * Revision 2.3  1995/03/07  16:52:03  john
  35.  * Fixed robots not moving without edtiro bug.
  36.  * 
  37.  * Revision 2.2  1995/03/06  16:10:20  mike
  38.  * Fix compile errors if building without editor.
  39.  * 
  40.  * Revision 2.1  1995/03/02  14:55:40  john
  41.  * Fixed bug with EDITOR never defined.
  42.  * 
  43.  * Revision 2.0  1995/02/27  11:33:10  john
  44.  * New version 2.0, which has no anonymous unions, builds with
  45.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  46.  * 
  47.  * Revision 1.1  1995/02/25  14:02:36  john
  48.  * Initial revision
  49.  * 
  50.  * 
  51.  */
  52.  
  53.  
  54. #pragma off (unreferenced)
  55. static char rcsid[] = "$Id: bmread.c,v 1.2 1998/08/08 15:42:19 nobody Exp $";
  56. #pragma on (unreferenced)
  57.  
  58. #include "settings.h"
  59.  
  60. #ifdef EDITOR
  61.  
  62. #include <stdio.h>
  63. #include <stdlib.h>
  64. #include <stdarg.h>
  65. #include <string.h>
  66.  
  67. #include "types.h"
  68. #include "inferno.h"
  69. #include "gr.h"
  70. #include "bm.h"
  71. #include "mem.h"
  72. #include "cflib.h"
  73. #include "mono.h"
  74. #include "error.h"
  75. #include "object.h"
  76. #include "vclip.h"
  77. #include "effects.h"
  78. #include "polyobj.h"
  79. #include "wall.h"
  80. #include "textures.h"
  81. #include "game.h"
  82. #include "multi.h"
  83.  
  84. #include "iff.h"
  85. #include "cfile.h"
  86.  
  87. #include "hostage.h"
  88. #include "powerup.h"
  89. #include "laser.h"
  90. #include "sounds.h"
  91. #include "piggy.h"
  92. #include "aistruct.h"
  93. #include "robot.h"
  94. #include "weapon.h"
  95. #include "gauges.h"
  96. #include "player.h"
  97. #include "fuelcen.h"
  98. #include "endlevel.h"
  99. #include "cntrlcen.h"
  100. #include "compbit.h"
  101. #include "args.h"
  102.  
  103.  
  104. #include "editor/texpage.h"
  105.  
  106. #define BM_NONE         -1
  107. #define BM_COCKPIT       0
  108. #define BM_TEXTURES      2
  109. #define BM_UNUSED            3
  110. #define BM_VCLIP             4
  111. #define BM_EFFECTS      5
  112. #define BM_ECLIP             6
  113. #define BM_WEAPON            7
  114. #define BM_DEMO          8
  115. #define BM_ROBOTEX      9
  116. #define BM_WALL_ANIMS   12
  117. #define BM_WCLIP            13
  118. #define BM_ROBOT            14
  119. #define BM_GAUGES           20
  120.  
  121. #define MAX_BITMAPS_PER_BRUSH 30
  122.  
  123. extern player_ship only_player_ship;        // In bm.c
  124.  
  125. static short        N_ObjBitmaps=0;
  126. static short        N_ObjBitmapPtrs=0;
  127. static int          Num_robot_ais = 0;
  128. int TmapList[MAX_TEXTURES];
  129. char    Powerup_names[MAX_POWERUP_TYPES][POWERUP_NAME_LENGTH];
  130. char    Robot_names[MAX_ROBOT_TYPES][ROBOT_NAME_LENGTH];
  131.  
  132. //---------------- Internal variables ---------------------------
  133. static int          Registered_only = 0;        //  Gets set by ! in column 1.
  134. static int          SuperX = -1;
  135. static int          Installed=0;
  136. static char         *arg;
  137. static short        tmap_count = 0;
  138. static short        texture_count = 0;
  139. static short        clip_count = 0;
  140. static short        clip_num;
  141. static short        sound_num;
  142. static short        frames;
  143. static float        time;
  144. static int          hit_sound = -1;
  145. static byte         bm_flag = BM_NONE;
  146. static int          abm_flag = 0;
  147. static int          rod_flag = 0;
  148. static short        wall_open_sound, wall_close_sound,wall_explodes,wall_blastable, wall_hidden;
  149. float       vlighting=0;
  150. static int          obj_eclip;
  151. static char         *dest_bm;       //clip number to play when destroyed
  152. static int          dest_vclip;     //what vclip to play when exploding
  153. static int          dest_eclip;     //what eclip to play when exploding
  154. static fix          dest_size;      //3d size of explosion
  155. static int          crit_clip;      //clip number to play when destroyed
  156. static int          crit_flag;      //flag if this is a destroyed eclip
  157. static int          tmap1_flag;     //flag if this is used as tmap_num (not tmap_num2)
  158. static int          num_sounds=0;
  159.  
  160.  
  161.  
  162. //------------------- Useful macros and variables ---------------
  163. #define REMOVE_EOL(s)       remove_char((s),'\n')
  164. #define REMOVE_COMMENTS(s)  remove_char((s),';')
  165. #define REMOVE_DOTS(s)      remove_char((s),'.')
  166.  
  167. #define IFTOK(str) if (!strcmp(arg, str))
  168. char *space = { " \t" };    
  169. //--unused-- char *equal = { "=" };
  170. char *equal_space = { " \t=" };
  171.  
  172. void remove_char( char * s, char c )
  173. {
  174.     char *p;
  175.     p = strchr(s,c);
  176.     if (p) *p = '\0';
  177. }
  178.  
  179. //---------------------------------------------------------------
  180. int compute_average_pixel(grs_bitmap *new)
  181. {
  182.     int row, column, color;
  183.     char    *pptr;
  184.     int total_red, total_green, total_blue;
  185.  
  186.     pptr = new->bm_data;
  187.  
  188.     total_red = 0;
  189.     total_green = 0;
  190.     total_blue = 0;
  191.  
  192.     for (row=0; row<new->bm_h; row++)
  193.         for (column=0; column<new->bm_w; column++) {
  194.             color = *pptr++;
  195.             total_red += gr_palette[color*3];
  196.             total_green += gr_palette[color*3+1];
  197.             total_blue += gr_palette[color*3+2];
  198.         }
  199.  
  200.     total_red /= (new->bm_h * new->bm_w);
  201.     total_green /= (new->bm_h * new->bm_w);
  202.     total_blue /= (new->bm_h * new->bm_w);
  203.  
  204.     return BM_XRGB(total_red/2, total_green/2, total_blue/2);
  205. }
  206.  
  207. //---------------------------------------------------------------
  208. // Loads a bitmap from either the piggy file, a r64 file, or a
  209. // whatever extension is passed.
  210.  
  211. void strip_ext(char *filename) {
  212.     char *p;
  213.     if ((p = strrchr(filename, '.'))) *p = 0;
  214. }
  215.  
  216. bitmap_index bm_load_sub( char * filename )
  217. {
  218.     bitmap_index bitmap_num;
  219.     grs_bitmap * new;
  220.     ubyte newpal[256*3];
  221.     int iff_error;      //reference parm to avoid warning message
  222.     char fname[20];
  223.  
  224.     bitmap_num.index = 0;
  225.  
  226. #ifdef SHAREWARE
  227.     if (Registered_only) {
  228.         //mprintf( 0, "Skipping registered-only bitmap '%s'\n", filename );
  229.         return bitmap_num;
  230.     }
  231. #endif
  232.  
  233.     strncpy(fname, filename, 20);
  234.     fname[19] = 0;
  235.     strip_ext(fname);
  236.  
  237.     bitmap_num=piggy_find_bitmap( fname );
  238.     if (bitmap_num.index)   {
  239.         //mprintf(( 0, "Found bitmap '%s' in pig!\n", fname ));
  240.         return bitmap_num;
  241.     }
  242.  
  243.     //MALLOC( new, grs_bitmap, 1 );//hack KRB
  244.     new = (grs_bitmap *)malloc(1*sizeof(grs_bitmap));
  245.     iff_error = iff_read_bitmap(filename,new,BM_LINEAR,newpal);
  246.     new->bm_selector=0;
  247.     if (iff_error != IFF_NO_ERROR)      {
  248.         mprintf((1, "File %s - IFF error: %s",filename,iff_errormsg(iff_error)));
  249.         Error("File %s - IFF error: %s",filename,iff_errormsg(iff_error));
  250.     }
  251.  
  252.     if ( iff_has_transparency )
  253.         gr_remap_bitmap_good( new, newpal, iff_transparent_color, SuperX );
  254.     else
  255.         gr_remap_bitmap_good( new, newpal, -1, SuperX );
  256.  
  257.     new->avg_color = compute_average_pixel(new);
  258.  
  259.     mprintf( (0, "N" ));
  260.     bitmap_num = piggy_register_bitmap( new, fname, 0 );
  261.     free( new );
  262.     return bitmap_num;
  263. }
  264.  
  265. void ab_load( char * filename, bitmap_index bmp[], int *nframes )
  266. {
  267.     grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
  268.     bitmap_index bi;
  269.     int i;
  270.     int iff_error;      //reference parm to avoid warning message
  271.     ubyte newpal[768];
  272.     char fname[20];
  273.     char tempname[20];
  274.  
  275. #ifdef SHAREWARE
  276.     if (Registered_only) {
  277.         Assert( bogus_bitmap_initialized != 0 );
  278.         mprintf(( 0, "Skipping registered-only animation '%s'\n", filename ));
  279.         bmp[0] = &bogus_bitmap;
  280.         *nframes = 1;
  281.         return;
  282.     }
  283. #endif
  284.  
  285.     strncpy(fname, filename, 20);
  286.     fname[19] = 0;
  287.     strip_ext(fname);
  288.     
  289.     for (i=0; i<MAX_BITMAPS_PER_BRUSH; i++ )    {
  290.         sprintf( tempname, "%s#%d", fname, i );
  291.         bi = piggy_find_bitmap( tempname );
  292.         if ( !bi.index )    
  293.             break;
  294.         bmp[i] = bi;
  295.         //mprintf(( 0, "Found animation frame %d, %s, in piggy file\n", i, tempname ));
  296.     }
  297.  
  298.     if (i) {
  299.         *nframes = i;
  300.         return;
  301.     }
  302.  
  303.     iff_error = iff_read_animbrush(filename,bm,MAX_BITMAPS_PER_BRUSH,nframes,&newpal);
  304.     if (iff_error != IFF_NO_ERROR)  {
  305.         mprintf((1,"File %s - IFF error: %s",filename,iff_errormsg(iff_error)));
  306.         Error("File %s - IFF error: %s",filename,iff_errormsg(iff_error));
  307.     }
  308.  
  309.     for (i=0;i< *nframes; i++)  {
  310.         bitmap_index new_bmp;
  311.         sprintf( tempname, "%s#%d", fname, i );
  312.         if ( iff_has_transparency )
  313.             gr_remap_bitmap_good( bm[i], newpal, iff_transparent_color, SuperX );
  314.         else
  315.             gr_remap_bitmap_good( bm[i], newpal, -1, SuperX );
  316.  
  317.         bm[i]->avg_color = compute_average_pixel(bm[i]);
  318.  
  319.         new_bmp = piggy_register_bitmap( bm[i], tempname, 0 );
  320.         free( bm[i] );
  321.         bmp[i] = new_bmp;
  322.         mprintf((0, "Registering frame %d, %s, in piggy file\n", i, tempname ));
  323.     }
  324. }
  325.  
  326. int ds_load( char * filename )  {
  327.     int i;
  328.     CFILE * cfp;
  329.     digi_sound new;
  330.     char fname[20];
  331.     char rawname[100];
  332.  
  333. #ifdef SHAREWARE
  334.     if (Registered_only) {
  335.         //mprintf( 0, "Skipping registered-only sound '%s'\n", filename );
  336.         return &bogus_sound;
  337.     }
  338. #endif
  339.  
  340.     strncpy(fname, filename, 20);
  341.     fname[19] = 0;
  342.     strip_ext(fname);
  343.     strcpy(rawname, fname);
  344.     strcat(rawname, ".raw");
  345.  
  346.     i=piggy_find_sound( fname );
  347.     if (i!=255) {
  348.         return i;
  349.     }
  350.  
  351.     cfp = cfopen( rawname, "rb" );
  352.  
  353.     if (cfp!=NULL) {
  354.         new.length  = cfilelength( cfp );
  355.         //MALLOC( new.data, ubyte, new.length );//hack by KRB
  356.         new.data = (ubyte *)malloc(new.length*sizeof(ubyte));
  357.         cfread( new.data, 1, new.length, cfp );
  358.         cfclose(cfp);
  359.         mprintf( (0, "S" ));
  360.         mprintf( (0, "<%s>", rawname ));
  361.     } else {
  362.         mprintf( (1, "Warning: Couldn't find '%s'\n", filename ));
  363.         return 255;
  364.     }
  365.     i = piggy_register_sound( &new, fname, 0 );
  366.     return i;
  367. }
  368.  
  369. //parse a float
  370. float get_float()
  371. {
  372.     char *xarg;
  373.  
  374.     xarg = strtok( NULL, space );
  375.     return atof( xarg );
  376. }
  377.  
  378. //parse an int
  379. int get_int()
  380. {
  381.     char *xarg;
  382.  
  383.     xarg = strtok( NULL, space );
  384.     return atoi( xarg );
  385. }
  386.  
  387. // rotates a byte left one bit, preserving the bit falling off the right
  388. //void
  389. //rotate_left(char *c)
  390. //{
  391. //  int found;
  392. //
  393. //  found = 0;
  394. //  if (*c & 0x80)
  395. //      found = 1;
  396. //  *c = *c << 1;
  397. //  if (found)
  398. //      *c |= 0x01;
  399. //}
  400.  
  401. #define LINEBUF_SIZE 600
  402.  
  403. int linenum;
  404.  
  405. //-----------------------------------------------------------------
  406. // Initializes all bitmaps from BITMAPS.TBL file.
  407. int bm_init_use_tbl()
  408. {
  409.     CFILE   * InfoFile;
  410.     char    inputline[LINEBUF_SIZE];
  411.     int i, have_bin_tbl;
  412.  
  413.     init_polygon_models();
  414.  
  415.     ObjType[0] = OL_PLAYER;
  416.     ObjId[0] = 0;
  417.     Num_total_object_types = 1;
  418.  
  419.     for (i=0; i<MAX_SOUNDS; i++ )   {
  420.         Sounds[i] = 255;
  421.         AltSounds[i] = 255;
  422.     }
  423.  
  424.     for (i=0; i<MAX_TEXTURES; i++ ) {
  425.         TmapInfo[i].eclip_num = -1;
  426.         TmapInfo[i].flags = 0;
  427.     }
  428.  
  429.     #ifndef SHAREWARE
  430.     for (i=0; i<MAX_HOSTAGES; i++ )
  431.         Hostage_face_clip[i].num_frames=0;
  432.     #endif
  433.  
  434.     Num_effects = 0;
  435.     for (i=0; i<MAX_EFFECTS; i++ ) {
  436.         //Effects[i].bm_ptr = (grs_bitmap **) -1;
  437.         Effects[i].changing_wall_texture = -1;
  438.         Effects[i].changing_object_texture = -1;
  439.         Effects[i].segnum = -1;
  440.         Effects[i].vc.num_frames = -1;      //another mark of being unused
  441.     }
  442.  
  443.     for (i=0;i<MAX_POLYGON_MODELS;i++)
  444.         Dying_modelnums[i] = Dead_modelnums[i] = -1;
  445.  
  446.     Num_vclips = 0;
  447.     for (i=0; i<VCLIP_MAXNUM; i++ ) {
  448.         Vclip[i].num_frames = -1;
  449.         Vclip[i].flags = 0;
  450.     }
  451.  
  452.     for (i=0; i<MAX_WALL_ANIMS; i++ )
  453.         WallAnims[i].num_frames = -1;
  454.     Num_wall_anims = 0;
  455.  
  456.     setbuf(stdout, NULL);   // unbuffered output via printf
  457.  
  458.     if (Installed)
  459.         return 1;
  460.  
  461.     Installed = 1;
  462.  
  463.     piggy_init();
  464.  
  465.     if ( FindArg( "-nobm" ) )   {
  466.         piggy_read_sounds();
  467.         return 0;
  468.     }
  469.  
  470.     // Open BITMAPS.TBL for reading.
  471.     have_bin_tbl = 0;
  472.     InfoFile = cfopen( "BITMAPS.TBL", "rb" );
  473.     if (InfoFile == NULL) {
  474.         InfoFile = cfopen("BITMAPS.BIN", "rb");
  475.         if (InfoFile == NULL)
  476.             Error("Missing BITMAPS.TBL and BITMAPS.BIN file\n");
  477.         have_bin_tbl = 1;
  478.     }
  479.     linenum = 0;
  480.     
  481.     cfseek( InfoFile, 0L, SEEK_SET);
  482.  
  483.     while (cfgets(inputline, LINEBUF_SIZE, InfoFile)) {
  484.         int l;
  485.         char *temp_ptr;
  486.  
  487.         linenum++;
  488.  
  489.         if (have_bin_tbl) {             // is this a binary tbl file
  490.             for (i = 0; i < strlen(inputline) - 1; i++) {
  491.                 encode_rotate_left(&(inputline[i]));
  492.                 inputline[i] = inputline[i] ^ BITMAP_TBL_XOR;
  493.                 encode_rotate_left(&(inputline[i]));
  494.             }
  495.         } else {
  496.             while (inputline[(l=strlen(inputline))-2]=='\\') {
  497.                 cfgets(inputline+l-2,LINEBUF_SIZE-(l-2), InfoFile);
  498.                 linenum++;
  499.             }
  500.         }
  501.  
  502.         REMOVE_EOL(inputline);
  503.         if (strchr(inputline, ';')!=NULL) REMOVE_COMMENTS(inputline);
  504.  
  505.         if (strlen(inputline) == LINEBUF_SIZE-1)
  506.             Error("Possible line truncation in BITMAPS.TBL on line %d\n",linenum);
  507.  
  508.         SuperX = -1;
  509.  
  510.         if ( (temp_ptr=strstr( inputline, "superx=" )) )    {
  511.             SuperX = atoi( &temp_ptr[7] );
  512.         }
  513.  
  514.         arg = strtok( inputline, space );
  515.         if (arg[0] == '@') {
  516.             arg++;
  517.             Registered_only = 1;
  518.         } else
  519.             Registered_only = 0;
  520.  
  521.         while (arg != NULL )
  522.             {
  523.             // Check all possible flags and defines.
  524.             if (*arg == '$') bm_flag = BM_NONE; // reset to no flags as default.
  525.  
  526.             IFTOK("$COCKPIT")           bm_flag = BM_COCKPIT;
  527.             else IFTOK("$GAUGES")       {bm_flag = BM_GAUGES;   clip_count = 0;}
  528.             else IFTOK("$SOUND")        bm_read_sound();
  529.             else IFTOK("$DOOR_ANIMS")   bm_flag = BM_WALL_ANIMS;
  530.             else IFTOK("$WALL_ANIMS")   bm_flag = BM_WALL_ANIMS;
  531.             else IFTOK("$TEXTURES")     bm_flag = BM_TEXTURES;
  532.             else IFTOK("$VCLIP")            {bm_flag = BM_VCLIP;        vlighting = 0;  clip_count = 0;}
  533.             else IFTOK("$ECLIP")            {bm_flag = BM_ECLIP;        vlighting = 0;  clip_count = 0; obj_eclip=0; dest_bm=NULL; dest_vclip=-1; dest_eclip=-1; dest_size=-1; crit_clip=-1; crit_flag=0; sound_num=-1;}
  534.             else IFTOK("$WCLIP")            {bm_flag = BM_WCLIP;        vlighting = 0;  clip_count = 0; wall_explodes = wall_blastable = 0; wall_open_sound=wall_close_sound=-1; tmap1_flag=0; wall_hidden=0;}
  535.  
  536.             else IFTOK("$EFFECTS")      {bm_flag = BM_EFFECTS;  clip_num = 0;}
  537.  
  538.             #ifdef EDITOR
  539.             else IFTOK("!METALS_FLAG")      TextureMetals = texture_count;
  540.             else IFTOK("!LIGHTS_FLAG")      TextureLights = texture_count;
  541.             else IFTOK("!EFFECTS_FLAG") TextureEffects = texture_count;
  542.             #endif
  543.  
  544.             else IFTOK("lighting")          TmapInfo[texture_count-1].lighting = fl2f(get_float());
  545.             else IFTOK("damage")            TmapInfo[texture_count-1].damage = fl2f(get_float());
  546.             else IFTOK("volatile")          TmapInfo[texture_count-1].flags |= TMI_VOLATILE;
  547.             //else IFTOK("Num_effects")     Num_effects = get_int();
  548.             else IFTOK("Num_wall_anims")    Num_wall_anims = get_int();
  549.             else IFTOK("clip_num")          clip_num = get_int();
  550.             else IFTOK("dest_bm")           dest_bm = strtok( NULL, space );
  551.             else IFTOK("dest_vclip")        dest_vclip = get_int();
  552.             else IFTOK("dest_eclip")        dest_eclip = get_int();
  553.             else IFTOK("dest_size")         dest_size = fl2f(get_float());
  554.             else IFTOK("crit_clip")         crit_clip = get_int();
  555.             else IFTOK("crit_flag")         crit_flag = get_int();
  556.             else IFTOK("sound_num")         sound_num = get_int();
  557.             else IFTOK("frames")            frames = get_int();
  558.             else IFTOK("time")              time = get_float();
  559.             else IFTOK("obj_eclip")         obj_eclip = get_int();
  560.             else IFTOK("hit_sound")         hit_sound = get_int();
  561.             else IFTOK("abm_flag")          abm_flag = get_int();
  562.             else IFTOK("tmap1_flag")        tmap1_flag = get_int();
  563.             else IFTOK("vlighting")         vlighting = get_float();
  564.             else IFTOK("rod_flag")          rod_flag = get_int();
  565.             else IFTOK("superx")            get_int();
  566.             else IFTOK("open_sound")        wall_open_sound = get_int();
  567.             else IFTOK("close_sound")       wall_close_sound = get_int();
  568.             else IFTOK("explodes")          wall_explodes = get_int();
  569.             else IFTOK("blastable")         wall_blastable = get_int();
  570.             else IFTOK("hidden")                wall_hidden = get_int();
  571.             else IFTOK("$ROBOT_AI")         bm_read_robot_ai();
  572.  
  573.             else IFTOK("$POWERUP")          {bm_read_powerup(0);        continue;}
  574.             else IFTOK("$POWERUP_UNUSED")   {bm_read_powerup(1);        continue;}
  575.             else IFTOK("$HOSTAGE")          {bm_read_hostage();     continue;}
  576.             else IFTOK("$HOSTAGE_FACE") {bm_read_hostage_face();continue;}
  577.             else IFTOK("$ROBOT")                {bm_read_robot();           continue;}
  578.             else IFTOK("$WEAPON")           {bm_read_weapon(0);     continue;}
  579.             else IFTOK("$WEAPON_UNUSED")    {bm_read_weapon(1);     continue;}
  580.             else IFTOK("$OBJECT")           {bm_read_object();      continue;}
  581.             else IFTOK("$PLAYER_SHIP")      {bm_read_player_ship(); continue;}
  582.  
  583.             else    {       //not a special token, must be a bitmap!
  584.  
  585.                 // Remove any illegal/unwanted spaces and tabs at this point.
  586.                 while ((*arg=='\t') || (*arg==' ')) arg++;
  587.                 if (*arg == '\0') { break; }    
  588.  
  589.                 // Otherwise, 'arg' is apparently a bitmap filename.
  590.                 // Load bitmap and process it below:
  591.                 bm_read_some_file();
  592.  
  593.             }
  594.  
  595.             arg = strtok( NULL, equal_space );
  596.             continue;
  597.       }
  598.     }
  599.  
  600.     NumTextures = texture_count;
  601.     Num_tmaps = tmap_count;
  602.     
  603.     cfclose( InfoFile );
  604.  
  605.     atexit(bm_close);
  606.  
  607.     Assert(N_robot_types == Num_robot_ais);     //should be one ai info per robot
  608.  
  609.     init_endlevel();        //this is here so endlevel bitmaps go into pig
  610.     
  611.     verify_textures();
  612.  
  613.     //check for refereced but unused clip count
  614.     for (i=0; i<MAX_EFFECTS; i++ )
  615.         if (    (
  616.                   (Effects[i].changing_wall_texture!=-1) ||
  617.                   (Effects[i].changing_object_texture!=-1)     
  618.              )
  619.              && (Effects[i].vc.num_frames==-1) )
  620.             Error("EClip %d referenced (by polygon object?), but not defined",i);
  621.  
  622.     #ifndef NDEBUG
  623.     {
  624.         int used;
  625.         for (i=used=0; i<num_sounds; i++ )
  626.             if (Sounds[i] != 255)
  627.                 used++;
  628.         mprintf((0,"Sound slots used: %d of %d, highest index %d\n",used,MAX_SOUNDS,num_sounds));
  629.     }
  630.     #endif
  631.  
  632.     piggy_read_sounds();
  633.  
  634.     #ifdef EDITOR
  635.     piggy_dump_all();
  636.     #endif
  637.  
  638.     return 0;
  639. }
  640.  
  641. void verify_textures()
  642. {
  643.     grs_bitmap * bmp;
  644.     int i,j;
  645.     j=0;
  646.     for (i=0; i<Num_tmaps; i++ )    {
  647.         bmp = &GameBitmaps[Textures[i].index];
  648.         if ( (bmp->bm_w!=64)||(bmp->bm_h!=64)||(bmp->bm_rowsize!=64) )  {
  649.             mprintf( (1, "ERROR: Texture '%s' isn't 64x64 !\n", TmapInfo[i].filename ));
  650.             j++;
  651.         } 
  652.     }
  653.     if (j) exit(1);
  654. }
  655.  
  656. //--unused-- void dump_all_transparent_textures()
  657. //--unused-- {
  658. //--unused--    FILE * fp;
  659. //--unused--    int i,j,k;
  660. //--unused--    ubyte * p;
  661. //--unused--    fp = fopen( "XPARENT.LST", "wt" );
  662. //--unused--    for (i=0; i<Num_tmaps; i++ )    {
  663. //--unused--        k = 0; 
  664. //--unused--        p = Textures[i]->bm_data;
  665. //--unused--        for (j=0; j<64*64; j++ )
  666. //--unused--            if ( (*p++)==255 ) k++;
  667. //--unused--        if ( k )    {
  668. //--unused--            fprintf( fp, "'%s' has %d transparent pixels\n", TmapInfo[i].filename, k );
  669. //--unused--        }               
  670. //--unused--    }
  671. //--unused--    fclose(fp); 
  672. //--unused-- }
  673.  
  674.  
  675. void bm_close()
  676. {
  677.     if (Installed)
  678.     {
  679.         piggy_close();
  680.         Installed=0;
  681.     }
  682. }
  683.  
  684. void set_lighting_flag(byte *bp)
  685. {
  686.     if (vlighting < 0)
  687.         *bp |= BM_FLAG_NO_LIGHTING;
  688.     else
  689.         *bp &= (0xff ^ BM_FLAG_NO_LIGHTING);
  690. }
  691.  
  692. set_texture_name(char *name)
  693. {
  694.     strcpy ( TmapInfo[texture_count].filename, name );
  695.     REMOVE_DOTS(TmapInfo[texture_count].filename);
  696. }
  697.  
  698. void bm_read_eclip()
  699. {
  700.     bitmap_index bitmap;
  701.  
  702.     Assert(clip_num < MAX_EFFECTS);
  703.  
  704.     if (clip_num+1 > Num_effects)
  705.         Num_effects = clip_num+1;
  706.  
  707.     Effects[clip_num].flags = 0;
  708.  
  709.     if (!abm_flag)  { 
  710.         bitmap = bm_load_sub(arg);
  711.  
  712.         Effects[clip_num].vc.play_time = fl2f(time);
  713.         Effects[clip_num].vc.num_frames = frames;
  714.         Effects[clip_num].vc.frame_time = fl2f(time)/frames;
  715.  
  716.         Assert(clip_count < frames);
  717.         Effects[clip_num].vc.frames[clip_count] = bitmap;
  718.         set_lighting_flag(&GameBitmaps[bitmap.index].bm_flags);
  719.  
  720.         Assert(!obj_eclip);     //obj eclips for non-abm files not supported!
  721.         Assert(crit_flag==0);
  722.  
  723.         if (clip_count == 0) {
  724.             Effects[clip_num].changing_wall_texture = texture_count;
  725.             Assert(tmap_count < MAX_TEXTURES);
  726.             TmapList[tmap_count++] = texture_count;
  727.             Textures[texture_count] = bitmap;
  728.             set_texture_name(arg);
  729.             Assert(texture_count < MAX_TEXTURES);
  730.             texture_count++;
  731.             TmapInfo[texture_count].eclip_num = clip_num;
  732.             NumTextures = texture_count;
  733.         }
  734.  
  735.         clip_count++;
  736.  
  737.     } else {
  738.         bitmap_index bm[MAX_BITMAPS_PER_BRUSH];
  739.         abm_flag = 0;
  740.  
  741.         ab_load( arg, bm, &Effects[clip_num].vc.num_frames );
  742.  
  743.         //printf("EC%d.", clip_num);
  744.         Effects[clip_num].vc.play_time = fl2f(time);
  745.         Effects[clip_num].vc.frame_time = Effects[clip_num].vc.play_time/Effects[clip_num].vc.num_frames;
  746.  
  747.         clip_count = 0; 
  748.         set_lighting_flag( &GameBitmaps[bm[clip_count].index].bm_flags);
  749.         Effects[clip_num].vc.frames[clip_count] = bm[clip_count];
  750.  
  751.         if (!obj_eclip && !crit_flag) {
  752.             Effects[clip_num].changing_wall_texture = texture_count;
  753.             Assert(tmap_count < MAX_TEXTURES);
  754.             TmapList[tmap_count++] = texture_count;
  755.             Textures[texture_count] = bm[clip_count];
  756.             set_texture_name( arg );
  757.             Assert(texture_count < MAX_TEXTURES);
  758.             TmapInfo[texture_count].eclip_num = clip_num;
  759.             texture_count++;
  760.             NumTextures = texture_count;
  761.         }
  762.  
  763.         if (obj_eclip) {
  764.  
  765.             if (Effects[clip_num].changing_object_texture == -1) {      //first time referenced
  766.                 Effects[clip_num].changing_object_texture = N_ObjBitmaps;       // XChange ObjectBitmaps
  767.                 N_ObjBitmaps++;
  768.             }
  769.  
  770.             ObjBitmaps[Effects[clip_num].changing_object_texture] = Effects[clip_num].vc.frames[0];
  771.         }
  772.  
  773.         //if for an object, Effects_bm_ptrs set in object load 
  774.  
  775.         for(clip_count=1;clip_count < Effects[clip_num].vc.num_frames; clip_count++) {
  776.             set_lighting_flag( &GameBitmaps[bm[clip_count].index].bm_flags);
  777.             Effects[clip_num].vc.frames[clip_count] = bm[clip_count];
  778.         }
  779.  
  780.     }
  781.  
  782.     Effects[clip_num].crit_clip = crit_clip;
  783.     Effects[clip_num].sound_num = sound_num;
  784.  
  785.     if (dest_bm) {          //deal with bitmap for blown up clip
  786.         char short_name[13];
  787.         int i;
  788.         strcpy(short_name,dest_bm);
  789.         REMOVE_DOTS(short_name);
  790.         for (i=0;i<texture_count;i++)
  791.             if (!stricmp(TmapInfo[i].filename,short_name))
  792.                 break;
  793.         if (i==texture_count) {
  794.             Textures[texture_count] = bm_load_sub(dest_bm);
  795.             strcpy( TmapInfo[texture_count].filename, short_name);
  796.             texture_count++;
  797.             Assert(texture_count < MAX_TEXTURES);
  798.             NumTextures = texture_count;
  799.         }
  800.         Effects[clip_num].dest_bm_num = i;
  801.  
  802.         if (dest_vclip==-1)
  803.             Error("Desctuction vclip missing on line %d",linenum);
  804.         if (dest_size==-1)
  805.             Error("Desctuction vclip missing on line %d",linenum);
  806.  
  807.         Effects[clip_num].dest_vclip = dest_vclip;
  808.         Effects[clip_num].dest_size = dest_size;
  809.  
  810.         Effects[clip_num].dest_eclip = dest_eclip;
  811.     }
  812.     else {
  813.         Effects[clip_num].dest_bm_num = -1;
  814.         Effects[clip_num].dest_eclip = -1;
  815.     }
  816.  
  817.     if (crit_flag)
  818.         Effects[clip_num].flags |= EF_CRITICAL;
  819. }
  820.  
  821.  
  822. void bm_read_gauges()
  823. {
  824.     bitmap_index bitmap;
  825.     int i, num_abm_frames;
  826.  
  827.     if (!abm_flag)  { 
  828.         bitmap = bm_load_sub(arg);
  829.         Assert(clip_count < MAX_GAUGE_BMS);
  830.         Gauges[clip_count] = bitmap;
  831.         clip_count++;
  832.     } else {
  833.         bitmap_index bm[MAX_BITMAPS_PER_BRUSH];
  834.         abm_flag = 0;
  835.         ab_load( arg, bm, &num_abm_frames );
  836.         for (i=clip_count; i<clip_count+num_abm_frames; i++) {
  837.             Assert(i < MAX_GAUGE_BMS);
  838.             Gauges[i] = bm[i-clip_count];
  839.         }
  840.         clip_count += num_abm_frames;
  841.     }
  842. }
  843.  
  844. void bm_read_wclip()
  845. {
  846.     bitmap_index bitmap;
  847.     Assert(clip_num < MAX_WALL_ANIMS);
  848.  
  849.     WallAnims[clip_num].flags = 0;
  850.  
  851.     if (wall_explodes)  WallAnims[clip_num].flags |= WCF_EXPLODES;
  852.     if (wall_blastable) WallAnims[clip_num].flags |= WCF_BLASTABLE;
  853.     if (wall_hidden)        WallAnims[clip_num].flags |= WCF_HIDDEN;
  854.     if (tmap1_flag)     WallAnims[clip_num].flags |= WCF_TMAP1;
  855.  
  856.     if (!abm_flag)  {
  857.         bitmap = bm_load_sub(arg);
  858.         if ( (WallAnims[clip_num].num_frames>-1) && (clip_count==0) )
  859.             Error( "Wall Clip %d is already used!", clip_num );
  860.         WallAnims[clip_num].play_time = fl2f(time);
  861.         WallAnims[clip_num].num_frames = frames;
  862.         //WallAnims[clip_num].frame_time = fl2f(time)/frames;
  863.         Assert(clip_count < frames);
  864.         WallAnims[clip_num].frames[clip_count++] = texture_count;
  865.         WallAnims[clip_num].open_sound = wall_open_sound;
  866.         WallAnims[clip_num].close_sound = wall_close_sound;
  867.         Textures[texture_count] = bitmap;
  868.         set_lighting_flag(&GameBitmaps[bitmap.index].bm_flags);
  869.         set_texture_name( arg );
  870.         Assert(texture_count < MAX_TEXTURES);
  871.         texture_count++;
  872.         NumTextures = texture_count;
  873.         if (clip_num >= Num_wall_anims) Num_wall_anims = clip_num+1;
  874.     } else {
  875.         bitmap_index bm[MAX_BITMAPS_PER_BRUSH];
  876.         int nframes;
  877.         if ( (WallAnims[clip_num].num_frames>-1)  )
  878.             Error( "AB_Wall clip %d is already used!", clip_num );
  879.         abm_flag = 0;
  880.         ab_load( arg, bm, &nframes );
  881.         WallAnims[clip_num].num_frames = nframes;
  882.         //printf("WC");
  883.         WallAnims[clip_num].play_time = fl2f(time);
  884.         //WallAnims[clip_num].frame_time = fl2f(time)/nframes;
  885.         WallAnims[clip_num].open_sound = wall_open_sound;
  886.         WallAnims[clip_num].close_sound = wall_close_sound;
  887.  
  888.         WallAnims[clip_num].close_sound = wall_close_sound;
  889.         strcpy(WallAnims[clip_num].filename, arg);
  890.         REMOVE_DOTS(WallAnims[clip_num].filename);  
  891.  
  892.         if (clip_num >= Num_wall_anims) Num_wall_anims = clip_num+1;
  893.  
  894.         set_lighting_flag(&GameBitmaps[bm[clip_count].index].bm_flags);
  895.  
  896.         for (clip_count=0;clip_count < WallAnims[clip_num].num_frames; clip_count++)    {
  897.             //printf("%d", clip_count);
  898.             Textures[texture_count] = bm[clip_count];
  899.             set_lighting_flag(&GameBitmaps[bm[clip_count].index].bm_flags);
  900.             WallAnims[clip_num].frames[clip_count] = texture_count;
  901.             REMOVE_DOTS(arg);
  902.             sprintf( TmapInfo[texture_count].filename, "%s#%d", arg, clip_count);
  903.             Assert(texture_count < MAX_TEXTURES);
  904.             texture_count++;
  905.             NumTextures = texture_count;
  906.         }
  907.     }
  908. }
  909.  
  910. void bm_read_vclip()
  911. {
  912.     bitmap_index bi;
  913.     Assert(clip_num < VCLIP_MAXNUM);
  914.  
  915.     if (!abm_flag)  {
  916.         if ( (Vclip[clip_num].num_frames>-1) && (clip_count==0)  )
  917.             Error( "Vclip %d is already used!", clip_num );
  918.         bi = bm_load_sub(arg);
  919.         Vclip[clip_num].play_time = fl2f(time);
  920.         Vclip[clip_num].num_frames = frames;
  921.         Vclip[clip_num].frame_time = fl2f(time)/frames;
  922.         Vclip[clip_num].light_value = fl2f(vlighting);
  923.         Vclip[clip_num].sound_num = sound_num;
  924.         set_lighting_flag(&GameBitmaps[bi.index].bm_flags);
  925.         Assert(clip_count < frames);
  926.         Vclip[clip_num].frames[clip_count++] = bi;
  927.         if (rod_flag) {
  928.             rod_flag=0;
  929.             Vclip[clip_num].flags |= VF_ROD;
  930.         }           
  931.  
  932.     } else  {
  933.         bitmap_index bm[MAX_BITMAPS_PER_BRUSH];
  934.         abm_flag = 0;
  935.         if ( (Vclip[clip_num].num_frames>-1)  )
  936.             Error( "AB_Vclip %d is already used!", clip_num );
  937.         ab_load( arg, bm, &Vclip[clip_num].num_frames );
  938.  
  939.         if (rod_flag) {
  940.             //int i;
  941.             rod_flag=0;
  942.             Vclip[clip_num].flags |= VF_ROD;
  943.         }           
  944.         //printf("VC");
  945.         Vclip[clip_num].play_time = fl2f(time);
  946.         Vclip[clip_num].frame_time = fl2f(time)/Vclip[clip_num].num_frames;
  947.         Vclip[clip_num].light_value = fl2f(vlighting);
  948.         Vclip[clip_num].sound_num = sound_num;
  949.         set_lighting_flag(&GameBitmaps[bm[clip_count].index].bm_flags);
  950.  
  951.         for (clip_count=0;clip_count < Vclip[clip_num].num_frames; clip_count++) {
  952.             //printf("%d", clip_count);
  953.             set_lighting_flag(&GameBitmaps[bm[clip_count].index].bm_flags);
  954.             Vclip[clip_num].frames[clip_count] = bm[clip_count];
  955.         }
  956.     }
  957. }
  958.  
  959. // ------------------------------------------------------------------------------
  960. void get4fix(fix *fixp)
  961. {
  962.     char    *curtext;
  963.     int i;
  964.  
  965.     for (i=0; i<NDL; i++) {
  966.         curtext = strtok(NULL, space);
  967.         fixp[i] = fl2f(atof(curtext));
  968.     }
  969. }
  970.  
  971. // ------------------------------------------------------------------------------
  972. void get4byte(byte *bytep)
  973. {
  974.     char    *curtext;
  975.     int i;
  976.  
  977.     for (i=0; i<NDL; i++) {
  978.         curtext = strtok(NULL, space);
  979.         bytep[i] = atoi(curtext);
  980.     }
  981. }
  982.  
  983. // ------------------------------------------------------------------------------
  984. //  Convert field of view from an angle in 0..360 to cosine.
  985. void adjust_field_of_view(fix *fovp)
  986. {
  987.     int     i;
  988.     fixang  tt;
  989.     float       ff;
  990.     fix     temp;
  991.  
  992.     for (i=0; i<NDL; i++) {
  993.         ff = - f2fl(fovp[i]);
  994.         if (ff > 179) {
  995.             mprintf((1, "Warning: Bogus field of view (%7.3f).  Must be in 0..179.\n", ff));
  996.             ff = 179;
  997.         }
  998.         ff = ff/360;
  999.         tt = fl2f(ff);
  1000.         fix_sincos(tt, &temp, &fovp[i]);
  1001.     }
  1002. }
  1003.  
  1004. void clear_to_end_of_line(void)
  1005. {
  1006.     arg = strtok( NULL, space );
  1007.     while (arg != NULL)
  1008.         arg = strtok( NULL, space );
  1009. }
  1010.  
  1011. bm_read_sound()
  1012. {
  1013.     int sound_num;
  1014.     int alt_sound_num;
  1015.  
  1016.     sound_num = get_int();
  1017.     alt_sound_num = get_int();
  1018.  
  1019.     if ( sound_num>=MAX_SOUNDS )
  1020.         Error( "Too many sound files.\n" );
  1021.  
  1022.     if (sound_num >= num_sounds)
  1023.         num_sounds = sound_num+1;
  1024.  
  1025.     arg = strtok(NULL, space);
  1026.  
  1027.     Sounds[sound_num] = ds_load(arg);
  1028.  
  1029.     if ( alt_sound_num == 0 )
  1030.         AltSounds[sound_num] = sound_num;
  1031.     else if (alt_sound_num < 0 )
  1032.         AltSounds[sound_num] = 255;
  1033.     else
  1034.         AltSounds[sound_num] = alt_sound_num;
  1035.  
  1036.     if (Sounds[sound_num] == 255)
  1037.         Error("Can't load soundfile <%s>",arg);
  1038. }
  1039.  
  1040. // ------------------------------------------------------------------------------
  1041. void bm_read_robot_ai() 
  1042. {
  1043.     char            *robotnum_text;
  1044.     int         robotnum;
  1045.     robot_info  *robptr;
  1046.  
  1047.     robotnum_text = strtok(NULL, space);
  1048.     robotnum = atoi(robotnum_text);
  1049.     Assert(robotnum < MAX_ROBOT_TYPES);
  1050.     robptr = &Robot_info[robotnum];
  1051.  
  1052.     Assert(robotnum == Num_robot_ais);      //make sure valid number
  1053.  
  1054. #ifdef SHAREWARE
  1055.     if (Registered_only) {
  1056.         Num_robot_ais++;
  1057.         clear_to_end_of_line();
  1058.         return;
  1059.     }
  1060. #endif
  1061.  
  1062.     Num_robot_ais++;
  1063.  
  1064.     get4fix(robptr->field_of_view);
  1065.     get4fix(robptr->firing_wait);
  1066.     get4byte(robptr->rapidfire_count);
  1067.     get4fix(robptr->turn_time);
  1068.     get4fix(robptr->fire_power);
  1069.     get4fix(robptr->shield);
  1070.     get4fix(robptr->max_speed);
  1071.     get4fix(robptr->circle_distance);
  1072.     get4byte(robptr->evade_speed);
  1073.  
  1074.     robptr->always_0xabcd   = 0xabcd;
  1075.  
  1076.     adjust_field_of_view(robptr->field_of_view);
  1077.  
  1078. }
  1079.  
  1080. //  ----------------------------------------------------------------------------------------------
  1081. //this will load a bitmap for a polygon models.  it puts the bitmap into
  1082. //the array ObjBitmaps[], and also deals with animating bitmaps
  1083. //returns a pointer to the bitmap
  1084. grs_bitmap *load_polymodel_bitmap(char *name)
  1085. {
  1086.     Assert(N_ObjBitmaps < MAX_OBJ_BITMAPS);
  1087.  
  1088. //  Assert( N_ObjBitmaps == N_ObjBitmapPtrs );
  1089.  
  1090.     if (name[0] == '%') {       //an animating bitmap!
  1091.         int eclip_num;
  1092.  
  1093.         eclip_num = atoi(name+1);
  1094.  
  1095.         if (Effects[eclip_num].changing_object_texture == -1) {     //first time referenced
  1096.             Effects[eclip_num].changing_object_texture = N_ObjBitmaps;
  1097.             ObjBitmapPtrs[N_ObjBitmapPtrs++] = N_ObjBitmaps;
  1098.             N_ObjBitmaps++;
  1099.         } else {
  1100.             ObjBitmapPtrs[N_ObjBitmapPtrs++] = Effects[eclip_num].changing_object_texture;
  1101.         }
  1102.         return NULL;
  1103.     }
  1104.     else    {
  1105.         ObjBitmaps[N_ObjBitmaps] = bm_load_sub(name);
  1106.         ObjBitmapPtrs[N_ObjBitmapPtrs++] = N_ObjBitmaps;
  1107.         N_ObjBitmaps++;
  1108.         return &GameBitmaps[ObjBitmaps[N_ObjBitmaps-1].index];
  1109.     }
  1110. }
  1111.  
  1112. #define MAX_MODEL_VARIANTS  4
  1113.  
  1114. // ------------------------------------------------------------------------------
  1115. void bm_read_robot()    
  1116. {
  1117.     char            *model_name[MAX_MODEL_VARIANTS];
  1118.     int         n_models,i;
  1119.     int         first_bitmap_num[MAX_MODEL_VARIANTS];
  1120.     char            *equal_ptr;
  1121.     int             exp1_vclip_num=-1;
  1122.     int         exp1_sound_num=-1;
  1123.     int             exp2_vclip_num=-1;
  1124.     int         exp2_sound_num=-1;
  1125.     fix         lighting = F1_0/2;      // Default
  1126.     fix         strength = F1_0*10;     // Default strength
  1127.     fix         mass = f1_0*4;
  1128.     fix         drag = f1_0/2;
  1129.     short       weapon_type = 0;
  1130.     int         g,s;
  1131.     char            name[ROBOT_NAME_LENGTH];
  1132.     int         contains_count=0, contains_id=0, contains_prob=0, contains_type=0;
  1133.     int         score_value=1000;
  1134.     int         cloak_type=0;       //  Default = this robot does not cloak
  1135.     int         attack_type=0;      //  Default = this robot attacks by firing (1=lunge)
  1136.     int         boss_flag=0;                //  Default = robot is not a boss.
  1137.     int         see_sound = ROBOT_SEE_SOUND_DEFAULT;
  1138.     int         attack_sound = ROBOT_ATTACK_SOUND_DEFAULT;
  1139.     int         claw_sound = ROBOT_CLAW_SOUND_DEFAULT;
  1140.  
  1141.     Assert(N_robot_types < MAX_ROBOT_TYPES);
  1142.  
  1143. #ifdef SHAREWARE
  1144.     if (Registered_only) {
  1145.         Robot_info[N_robot_types].model_num = -1;
  1146.         N_robot_types++;
  1147.         Num_total_object_types++;
  1148.         clear_to_end_of_line();
  1149.         return;
  1150.     }
  1151. #endif
  1152.  
  1153.     model_name[0] = strtok( NULL, space );
  1154.     first_bitmap_num[0] = N_ObjBitmapPtrs;
  1155.     n_models = 1;
  1156.  
  1157.     // Process bitmaps 
  1158.     bm_flag=BM_ROBOT;
  1159.     arg = strtok( NULL, space ); 
  1160.     while (arg!=NULL)   {
  1161.         equal_ptr = strchr( arg, '=' );
  1162.         if ( equal_ptr )    {
  1163.             *equal_ptr='\0';
  1164.             equal_ptr++;
  1165.             // if we have john=cool, arg is 'john' and equal_ptr is 'cool'
  1166.             if (!stricmp( arg, "exp1_vclip" ))  {
  1167.                 exp1_vclip_num = atoi(equal_ptr);
  1168.             } else if (!stricmp( arg, "exp2_vclip" ))   {
  1169.                 exp2_vclip_num = atoi(equal_ptr);
  1170.             } else if (!stricmp( arg, "exp1_sound" ))   {
  1171.                 exp1_sound_num = atoi(equal_ptr);
  1172.             } else if (!stricmp( arg, "exp2_sound" ))   {
  1173.                 exp2_sound_num = atoi(equal_ptr);
  1174.             } else if (!stricmp( arg, "lighting" )) {
  1175.                 lighting = fl2f(atof(equal_ptr));
  1176.                 if ( (lighting < 0) || (lighting > F1_0 )) {
  1177.                     mprintf( (1, "In bitmaps.tbl, lighting value of %.2f is out of range 0..1.\n", f2fl(lighting)));
  1178.                     Error( "In bitmaps.tbl, lighting value of %.2f is out of range 0..1.\n", f2fl(lighting));
  1179.                 }
  1180.             } else if (!stricmp( arg, "weapon_type" )) {
  1181.                 weapon_type = atoi(equal_ptr);
  1182.             } else if (!stricmp( arg, "strength" )) {
  1183.                 strength = i2f(atoi(equal_ptr));
  1184.             } else if (!stricmp( arg, "mass" )) {
  1185.                 mass = fl2f(atof(equal_ptr));
  1186.             } else if (!stricmp( arg, "drag" )) {
  1187.                 drag = fl2f(atof(equal_ptr));
  1188.             } else if (!stricmp( arg, "contains_id" )) {
  1189.                 contains_id = atoi(equal_ptr);
  1190.             } else if (!stricmp( arg, "contains_type" )) {
  1191.                 contains_type = atoi(equal_ptr);
  1192.             } else if (!stricmp( arg, "contains_count" )) {
  1193.                 contains_count = atoi(equal_ptr);
  1194.             } else if (!stricmp( arg, "contains_prob" )) {
  1195.                 contains_prob = atoi(equal_ptr);
  1196.             } else if (!stricmp( arg, "cloak_type" )) {
  1197.                 cloak_type = atoi(equal_ptr);
  1198.             } else if (!stricmp( arg, "attack_type" )) {
  1199.                 attack_type = atoi(equal_ptr);
  1200.             } else if (!stricmp( arg, "boss" )) {
  1201.                 boss_flag = atoi(equal_ptr);
  1202.             } else if (!stricmp( arg, "score_value" )) {
  1203.                 score_value = atoi(equal_ptr);
  1204.             } else if (!stricmp( arg, "see_sound" )) {
  1205.                 see_sound = atoi(equal_ptr);
  1206.             } else if (!stricmp( arg, "attack_sound" )) {
  1207.                 attack_sound = atoi(equal_ptr);
  1208.             } else if (!stricmp( arg, "claw_sound" )) {
  1209.                 claw_sound = atoi(equal_ptr);
  1210.             } else if (!stricmp( arg, "name" )) {
  1211.                 Assert(strlen(equal_ptr) < ROBOT_NAME_LENGTH);  //  Oops, name too long.
  1212.                 strcpy(name, &equal_ptr[1]);
  1213.                 name[strlen(name)-1] = 0;
  1214.             } else if (!stricmp( arg, "simple_model" )) {
  1215.                 model_name[n_models] = equal_ptr;
  1216.                 first_bitmap_num[n_models] = N_ObjBitmapPtrs;
  1217.                 n_models++;
  1218.             } else {
  1219.                 mprintf( (1, "Invalid parameter, %s=%s in bitmaps.tbl\n", arg, equal_ptr ));
  1220.             }       
  1221.         } else {            // Must be a texture specification...
  1222.             load_polymodel_bitmap(arg);
  1223.         }
  1224.         arg = strtok( NULL, space );
  1225.     }
  1226.  
  1227.     //clear out anim info
  1228.     for (g=0;g<MAX_GUNS+1;g++)
  1229.         for (s=0;s<N_ANIM_STATES;s++)
  1230.             Robot_info[N_robot_types].anim_states[g][s].n_joints = 0;   //inialize to zero
  1231.  
  1232.     first_bitmap_num[n_models] = N_ObjBitmapPtrs;
  1233.  
  1234.     for (i=0;i<n_models;i++) {
  1235.         int n_textures;
  1236.         int model_num,last_model_num;
  1237.  
  1238.         n_textures = first_bitmap_num[i+1] - first_bitmap_num[i];
  1239.  
  1240.         model_num = load_polygon_model(model_name[i],n_textures,first_bitmap_num[i],(i==0)?&Robot_info[N_robot_types]:NULL);
  1241.  
  1242.         if (i==0)
  1243.             Robot_info[N_robot_types].model_num = model_num;
  1244.         else
  1245.             Polygon_models[last_model_num].simpler_model = model_num+1;
  1246.  
  1247.         last_model_num = model_num;
  1248.     }
  1249.  
  1250.     ObjType[Num_total_object_types] = OL_ROBOT;
  1251.     ObjId[Num_total_object_types] = N_robot_types;
  1252.  
  1253.     Robot_info[N_robot_types].exp1_vclip_num = exp1_vclip_num;
  1254.     Robot_info[N_robot_types].exp2_vclip_num = exp2_vclip_num;
  1255.     Robot_info[N_robot_types].exp1_sound_num = exp1_sound_num;
  1256.     Robot_info[N_robot_types].exp2_sound_num = exp2_sound_num;
  1257.     Robot_info[N_robot_types].lighting = lighting;
  1258.     Robot_info[N_robot_types].weapon_type = weapon_type;
  1259.     Robot_info[N_robot_types].strength = strength;
  1260.     Robot_info[N_robot_types].mass = mass;
  1261.     Robot_info[N_robot_types].drag = drag;
  1262.     Robot_info[N_robot_types].cloak_type = cloak_type;
  1263.     Robot_info[N_robot_types].attack_type = attack_type;
  1264.     Robot_info[N_robot_types].boss_flag = boss_flag;
  1265.  
  1266.     Robot_info[N_robot_types].contains_id = contains_id;
  1267.     Robot_info[N_robot_types].contains_count = contains_count;
  1268.     Robot_info[N_robot_types].contains_prob = contains_prob;
  1269.     Robot_info[N_robot_types].score_value = score_value;
  1270.     Robot_info[N_robot_types].see_sound = see_sound;
  1271.     Robot_info[N_robot_types].attack_sound = attack_sound;
  1272.     Robot_info[N_robot_types].claw_sound = claw_sound;
  1273.  
  1274.     if (contains_type)
  1275.         Robot_info[N_robot_types].contains_type = OBJ_ROBOT;
  1276.     else
  1277.         Robot_info[N_robot_types].contains_type = OBJ_POWERUP;
  1278.  
  1279.     strcpy(Robot_names[N_robot_types], name);
  1280.  
  1281.     N_robot_types++;
  1282.     Num_total_object_types++;
  1283. }
  1284.  
  1285. //read a polygon object of some sort
  1286. void bm_read_object()
  1287. {
  1288.     char *model_name, *model_name_dead=NULL;
  1289.     int first_bitmap_num, first_bitmap_num_dead, n_normal_bitmaps;
  1290.     char *equal_ptr;
  1291.     short model_num;
  1292.     short explosion_vclip_num = -1;
  1293.     short explosion_sound_num = SOUND_ROBOT_DESTROYED;
  1294.     fix lighting = F1_0/2;      // Default
  1295.     int type=-1;
  1296.     fix strength=0;
  1297.  
  1298.     model_name = strtok( NULL, space );
  1299.  
  1300.     // Process bitmaps 
  1301.     bm_flag = BM_NONE;
  1302.     arg = strtok( NULL, space ); 
  1303.     first_bitmap_num = N_ObjBitmapPtrs;
  1304.  
  1305.     while (arg!=NULL)   {
  1306.  
  1307.         equal_ptr = strchr( arg, '=' );
  1308.  
  1309.         if ( equal_ptr )    {
  1310.             *equal_ptr='\0';
  1311.             equal_ptr++;
  1312.  
  1313.             // if we have john=cool, arg is 'john' and equal_ptr is 'cool'
  1314.  
  1315.             if (!stricmp(arg,"type")) {
  1316.                 if (!stricmp(equal_ptr,"controlcen"))
  1317.                     type = OL_CONTROL_CENTER;
  1318.                 else if (!stricmp(equal_ptr,"clutter"))
  1319.                     type = OL_CLUTTER;
  1320.                 else if (!stricmp(equal_ptr,"exit"))
  1321.                     type = OL_EXIT;
  1322.             }
  1323.             else if (!stricmp( arg, "exp_vclip" ))  {
  1324.                 explosion_vclip_num = atoi(equal_ptr);
  1325.             } else if (!stricmp( arg, "dead_pof" )) {
  1326.                 model_name_dead = equal_ptr;
  1327.                 first_bitmap_num_dead=N_ObjBitmapPtrs;
  1328.             } else if (!stricmp( arg, "exp_sound" ))    {
  1329.                 explosion_sound_num = atoi(equal_ptr);
  1330.             } else if (!stricmp( arg, "lighting" )) {
  1331.                 lighting = fl2f(atof(equal_ptr));
  1332.                 if ( (lighting < 0) || (lighting > F1_0 )) {
  1333.                     mprintf( (1, "In bitmaps.tbl, lighting value of %.2f is out of range 0..1.\n", f2fl(lighting)));
  1334.                     Error( "In bitmaps.tbl, lighting value of %.2f is out of range 0..1.\n", f2fl(lighting));
  1335.                 }
  1336.             } else if (!stricmp( arg, "strength" )) {
  1337.                 strength = fl2f(atof(equal_ptr));
  1338.             } else {
  1339.                 mprintf( (1, "Invalid parameter, %s=%s in bitmaps.tbl\n", arg, equal_ptr ));
  1340.             }       
  1341.         } else {            // Must be a texture specification...
  1342.             load_polymodel_bitmap(arg);
  1343.         }
  1344.         arg = strtok( NULL, space );
  1345.     }
  1346.  
  1347.     if ( model_name_dead )
  1348.         n_normal_bitmaps = first_bitmap_num_dead-first_bitmap_num;
  1349.     else
  1350.         n_normal_bitmaps = N_ObjBitmapPtrs-first_bitmap_num;
  1351.  
  1352.     model_num = load_polygon_model(model_name,n_normal_bitmaps,first_bitmap_num,NULL);
  1353.  
  1354.     if (type == OL_CONTROL_CENTER)
  1355.         N_controlcen_guns = read_model_guns(model_name,controlcen_gun_points,controlcen_gun_dirs,NULL);
  1356.  
  1357.     if ( model_name_dead )
  1358.         Dead_modelnums[model_num]  = load_polygon_model(model_name_dead,N_ObjBitmapPtrs-first_bitmap_num_dead,first_bitmap_num_dead,NULL);
  1359.     else
  1360.         Dead_modelnums[model_num] = -1;
  1361.  
  1362.     if (type == -1)
  1363.         Error("No object type specfied for object in BITMAPS.TBL on line %d\n",linenum);
  1364.  
  1365.     ObjType[Num_total_object_types] = type;
  1366.     ObjId[Num_total_object_types] = model_num;
  1367.     ObjStrength[Num_total_object_types] = strength;
  1368.     
  1369.     //printf( "Object type %d is a control center\n", Num_total_object_types );
  1370.     Num_total_object_types++;
  1371.  
  1372.     if (type == OL_EXIT) {
  1373.         exit_modelnum = model_num;
  1374.         destroyed_exit_modelnum = Dead_modelnums[model_num];
  1375.     }
  1376.  
  1377. }
  1378.  
  1379. void bm_read_player_ship()
  1380. {
  1381.     char    *model_name_dying=NULL;
  1382.     char    *model_name[MAX_MODEL_VARIANTS];
  1383.     int n_models=0,i;
  1384.     int first_bitmap_num[MAX_MODEL_VARIANTS];
  1385.     char *equal_ptr;
  1386.     robot_info ri;
  1387.     int last_multi_bitmap_num=-1;
  1388.  
  1389.     // Process bitmaps 
  1390.     bm_flag = BM_NONE;
  1391.  
  1392.     arg = strtok( NULL, space ); 
  1393.  
  1394.     Player_ship->mass = Player_ship->drag = 0;  //stupid defaults
  1395.     Player_ship->expl_vclip_num = -1;
  1396.  
  1397.     while (arg!=NULL)   {
  1398.  
  1399.         equal_ptr = strchr( arg, '=' );
  1400.  
  1401.         if ( equal_ptr )    {
  1402.  
  1403.             *equal_ptr='\0';
  1404.             equal_ptr++;
  1405.  
  1406.             // if we have john=cool, arg is 'john' and equal_ptr is 'cool'
  1407.  
  1408.             if (!stricmp( arg, "model" )) {
  1409.                 Assert(n_models==0);
  1410.                 model_name[0] = equal_ptr;
  1411.                 first_bitmap_num[0] = N_ObjBitmapPtrs;
  1412.                 n_models = 1;
  1413.             } else if (!stricmp( arg, "simple_model" )) {
  1414.                 model_name[n_models] = equal_ptr;
  1415.                 first_bitmap_num[n_models] = N_ObjBitmapPtrs;
  1416.                 n_models++;
  1417.  
  1418.                 if (First_multi_bitmap_num!=-1 && last_multi_bitmap_num==-1)
  1419.                     last_multi_bitmap_num=N_ObjBitmapPtrs;
  1420.             }
  1421.             else if (!stricmp( arg, "mass" ))
  1422.                 Player_ship->mass = fl2f(atof(equal_ptr));
  1423.             else if (!stricmp( arg, "drag" ))
  1424.                 Player_ship->drag = fl2f(atof(equal_ptr));
  1425. //          else if (!stricmp( arg, "low_thrust" ))
  1426. //              Player_ship->low_thrust = fl2f(atof(equal_ptr));
  1427.             else if (!stricmp( arg, "max_thrust" ))
  1428.                 Player_ship->max_thrust = fl2f(atof(equal_ptr));
  1429.             else if (!stricmp( arg, "reverse_thrust" ))
  1430.                 Player_ship->reverse_thrust = fl2f(atof(equal_ptr));
  1431.             else if (!stricmp( arg, "brakes" ))
  1432.                 Player_ship->brakes = fl2f(atof(equal_ptr));
  1433.             else if (!stricmp( arg, "wiggle" ))
  1434.                 Player_ship->wiggle = fl2f(atof(equal_ptr));
  1435.             else if (!stricmp( arg, "max_rotthrust" ))
  1436.                 Player_ship->max_rotthrust = fl2f(atof(equal_ptr));
  1437.             else if (!stricmp( arg, "dying_pof" ))
  1438.                 model_name_dying = equal_ptr;
  1439.             else if (!stricmp( arg, "expl_vclip_num" ))
  1440.                 Player_ship->expl_vclip_num=atoi(equal_ptr);
  1441.             else {
  1442.                 mprintf( (1, "Invalid parameter, %s=%s in bitmaps.tbl\n", arg, equal_ptr ));
  1443.             }       
  1444.         }
  1445.         else if (!stricmp( arg, "multi_textures" )) {
  1446.  
  1447.             First_multi_bitmap_num = N_ObjBitmapPtrs;
  1448.             first_bitmap_num[n_models] = N_ObjBitmapPtrs;
  1449.  
  1450.         }
  1451.         else            // Must be a texture specification...
  1452.  
  1453.             load_polymodel_bitmap(arg);
  1454.  
  1455.         arg = strtok( NULL, space );
  1456.     }
  1457.  
  1458.     Assert(model_name != NULL);
  1459.  
  1460.     if (First_multi_bitmap_num!=-1 && last_multi_bitmap_num==-1)
  1461.         last_multi_bitmap_num=N_ObjBitmapPtrs;
  1462.  
  1463.     if (First_multi_bitmap_num==-1)
  1464.         first_bitmap_num[n_models] = N_ObjBitmapPtrs;
  1465.  
  1466.     Assert(last_multi_bitmap_num-First_multi_bitmap_num == (MAX_NUM_NET_PLAYERS-1)*2);
  1467.  
  1468.     for (i=0;i<n_models;i++) {
  1469.         int n_textures;
  1470.         int model_num,last_model_num;
  1471.  
  1472.         n_textures = first_bitmap_num[i+1] - first_bitmap_num[i];
  1473.  
  1474.         model_num = load_polygon_model(model_name[i],n_textures,first_bitmap_num[i],(i==0)?&ri:NULL);
  1475.  
  1476.         if (i==0)
  1477.             Player_ship->model_num = model_num;
  1478.         else
  1479.             Polygon_models[last_model_num].simpler_model = model_num+1;
  1480.  
  1481.         last_model_num = model_num;
  1482.     }
  1483.  
  1484.     if ( model_name_dying ) {
  1485.         Assert(n_models);
  1486.         Dying_modelnums[Player_ship->model_num]  = load_polygon_model(model_name_dying,first_bitmap_num[1]-first_bitmap_num[0],first_bitmap_num[0],NULL);
  1487.     }
  1488.  
  1489.     Assert(ri.n_guns == N_PLAYER_GUNS);
  1490.  
  1491.     //calc player gun positions
  1492.  
  1493.     {
  1494.         polymodel *pm;
  1495.         robot_info *r;
  1496.         vms_vector pnt;
  1497.         int mn;             //submodel number
  1498.         int gun_num;
  1499.     
  1500.         r = &ri;
  1501.         pm = &Polygon_models[Player_ship->model_num];
  1502.  
  1503.         for (gun_num=0;gun_num<r->n_guns;gun_num++) {
  1504.  
  1505.             pnt = r->gun_points[gun_num];
  1506.             mn = r->gun_submodels[gun_num];
  1507.         
  1508.             //instance up the tree for this gun
  1509.             while (mn != 0) {
  1510.                 vm_vec_add2(&pnt,&pm->submodel_offsets[mn]);
  1511.                 mn = pm->submodel_parents[mn];
  1512.             }
  1513.  
  1514.             Player_ship->gun_points[gun_num] = pnt;
  1515.         
  1516.         }
  1517.     }
  1518.  
  1519.  
  1520. }
  1521.  
  1522. void bm_read_some_file()
  1523. {
  1524.  
  1525.     switch (bm_flag) {
  1526.     case BM_COCKPIT:    {
  1527.         bitmap_index bitmap;
  1528.         bitmap = bm_load_sub(arg);
  1529.         Assert( Num_cockpits < N_COCKPIT_BITMAPS );
  1530.         cockpit_bitmap[Num_cockpits++] = bitmap;
  1531.  
  1532.         //bm_flag = BM_NONE;
  1533.         }
  1534.         break;
  1535.     case BM_GAUGES:
  1536.         bm_read_gauges();
  1537.         break;
  1538.     case BM_WEAPON:
  1539.         bm_read_weapon(0);
  1540.         break;
  1541.     case BM_VCLIP:
  1542.         bm_read_vclip();
  1543.         break;                  
  1544.     case BM_ECLIP:
  1545.         bm_read_eclip();
  1546.         break;
  1547.     case BM_TEXTURES:           {
  1548.         bitmap_index bitmap;
  1549.         bitmap = bm_load_sub(arg);
  1550.         Assert(tmap_count < MAX_TEXTURES);
  1551.         TmapList[tmap_count++] = texture_count;
  1552.         Textures[texture_count] = bitmap;
  1553.         set_texture_name( arg );
  1554.         Assert(texture_count < MAX_TEXTURES);
  1555.         texture_count++;
  1556.         NumTextures = texture_count;
  1557.         }
  1558.         break;
  1559.     case BM_WCLIP:
  1560.         bm_read_wclip();
  1561.         break;
  1562.     default:
  1563.         break;
  1564.     }
  1565. }
  1566.  
  1567. // ------------------------------------------------------------------------------
  1568. //  If unused_flag is set, then this is just a placeholder.  Don't actually reference vclips or load bbms.
  1569. void bm_read_weapon(int unused_flag)
  1570. {
  1571.     int i,n;
  1572.     int n_models=0;
  1573.     char    *equal_ptr;
  1574.     char    *pof_file_inner=NULL;
  1575.     char    *model_name[MAX_MODEL_VARIANTS];
  1576.     int first_bitmap_num[MAX_MODEL_VARIANTS];
  1577.     int lighted;                    //flag for whether is a texture is lighted
  1578.  
  1579.     Assert(N_weapon_types < MAX_WEAPON_TYPES);
  1580.  
  1581.     n = N_weapon_types;
  1582.     N_weapon_types++;
  1583.  
  1584.     if (unused_flag) {
  1585.         clear_to_end_of_line();
  1586.         return;
  1587.     }
  1588.  
  1589. #ifdef SHAREWARE
  1590.     if (Registered_only) {
  1591.         clear_to_end_of_line();
  1592.         return;
  1593.     }
  1594. #endif
  1595.  
  1596.     // Initialize weapon array
  1597.     Weapon_info[n].render_type = WEAPON_RENDER_NONE;        // 0=laser, 1=blob, 2=object
  1598.     Weapon_info[n].bitmap.index = 0;
  1599.     Weapon_info[n].model_num = -1;
  1600.     Weapon_info[n].model_num_inner = -1;
  1601.     Weapon_info[n].blob_size = 0x1000;                                  // size of blob
  1602.     Weapon_info[n].flash_vclip = -1;
  1603.     Weapon_info[n].flash_sound = SOUND_LASER_FIRED;
  1604.     Weapon_info[n].flash_size = 0;
  1605.     Weapon_info[n].robot_hit_vclip = -1;
  1606.     Weapon_info[n].robot_hit_sound = -1;
  1607.     Weapon_info[n].wall_hit_vclip = -1;
  1608.     Weapon_info[n].wall_hit_sound = -1;
  1609.     Weapon_info[n].impact_size = 0;
  1610.     for (i=0; i<NDL; i++) {
  1611.         Weapon_info[n].strength[i] = F1_0;
  1612.         Weapon_info[n].speed[i] = F1_0*10;
  1613.     }
  1614.     Weapon_info[n].mass = F1_0;
  1615.     Weapon_info[n].thrust = 0;
  1616.     Weapon_info[n].drag = 0;
  1617.     Weapon_info[n].persistent = 0;
  1618.  
  1619.     Weapon_info[n].energy_usage = 0;                    //  How much fuel is consumed to fire this weapon.
  1620.     Weapon_info[n].ammo_usage = 0;                  //  How many units of ammunition it uses.
  1621.     Weapon_info[n].fire_wait = F1_0/4;              //  Time until this weapon can be fired again.
  1622.     Weapon_info[n].fire_count = 1;                  //  Number of bursts fired from EACH GUN per firing.  For weapons which fire from both sides, 3*fire_count shots will be fired.
  1623.     Weapon_info[n].damage_radius = 0;               //  Radius of damage for missiles, not lasers.  Does damage to objects within this radius of hit point.
  1624. //--01/19/95, mk--  Weapon_info[n].damage_force = 0;                    //  Force (movement) due to explosion
  1625.     Weapon_info[n].destroyable = 1;                 //  Weapons default to destroyable
  1626.     Weapon_info[n].matter = 0;                          //  Weapons default to not being constructed of matter (they are energy!)
  1627.     Weapon_info[n].bounce = 0;                          //  Weapons default to not bouncing off walls
  1628.  
  1629.     Weapon_info[n].lifetime = WEAPON_DEFAULT_LIFETIME;                  //  Number of bursts fired from EACH GUN per firing.  For weapons which fire from both sides, 3*fire_count shots will be fired.
  1630.  
  1631.     Weapon_info[n].po_len_to_width_ratio = F1_0*10;
  1632.  
  1633.     Weapon_info[n].picture.index = 0;
  1634.     Weapon_info[n].homing_flag = 0;
  1635.  
  1636.     // Process arguments
  1637.     arg = strtok( NULL, space ); 
  1638.  
  1639.     lighted = 1;            //assume first texture is lighted
  1640.  
  1641.     while (arg!=NULL)   {
  1642.         equal_ptr = strchr( arg, '=' );
  1643.         if ( equal_ptr )    {
  1644.             *equal_ptr='\0';
  1645.             equal_ptr++;
  1646.             // if we have john=cool, arg is 'john' and equal_ptr is 'cool'
  1647.             if (!stricmp( arg, "laser_bmp" ))   {
  1648.                 // Load bitmap with name equal_ptr
  1649.  
  1650.                 Weapon_info[n].bitmap = bm_load_sub(equal_ptr);     //load_polymodel_bitmap(equal_ptr);
  1651.                 Weapon_info[n].render_type = WEAPON_RENDER_LASER;
  1652.  
  1653.             } else if (!stricmp( arg, "blob_bmp" )) {
  1654.                 // Load bitmap with name equal_ptr
  1655.  
  1656.                 Weapon_info[n].bitmap = bm_load_sub(equal_ptr);     //load_polymodel_bitmap(equal_ptr);
  1657.                 Weapon_info[n].render_type = WEAPON_RENDER_BLOB;
  1658.  
  1659.             } else if (!stricmp( arg, "weapon_vclip" )) {
  1660.                 // Set vclip to play for this weapon.
  1661.                 Weapon_info[n].bitmap.index = 0;
  1662.                 Weapon_info[n].render_type = WEAPON_RENDER_VCLIP;
  1663.                 Weapon_info[n].weapon_vclip = atoi(equal_ptr);
  1664.  
  1665.             } else if (!stricmp( arg, "none_bmp" )) {
  1666.                 Weapon_info[n].bitmap = bm_load_sub(equal_ptr);
  1667.                 Weapon_info[n].render_type = WEAPON_RENDER_NONE;
  1668.  
  1669.             } else if (!stricmp( arg, "weapon_pof" ))   {
  1670.                 // Load pof file
  1671.                 Assert(n_models==0);
  1672.                 model_name[0] = equal_ptr;
  1673.                 first_bitmap_num[0] = N_ObjBitmapPtrs;
  1674.                 n_models=1;
  1675.             } else if (!stricmp( arg, "simple_model" )) {
  1676.                 model_name[n_models] = equal_ptr;
  1677.                 first_bitmap_num[n_models] = N_ObjBitmapPtrs;
  1678.                 n_models++;
  1679.             } else if (!stricmp( arg, "weapon_pof_inner" )) {
  1680.                 // Load pof file
  1681.                 pof_file_inner = equal_ptr;
  1682.             } else if (!stricmp( arg, "strength" )) {
  1683.                 for (i=0; i<NDL-1; i++) {
  1684.                     Weapon_info[n].strength[i] = i2f(atoi(equal_ptr));
  1685.                     equal_ptr = strtok(NULL, space);
  1686.                 }
  1687.                 Weapon_info[n].strength[i] = i2f(atoi(equal_ptr));
  1688.             } else if (!stricmp( arg, "mass" )) {
  1689.                 Weapon_info[n].mass = fl2f(atof(equal_ptr));
  1690.             } else if (!stricmp( arg, "drag" )) {
  1691.                 Weapon_info[n].drag = fl2f(atof(equal_ptr));
  1692.             } else if (!stricmp( arg, "thrust" )) {
  1693.                 Weapon_info[n].thrust = fl2f(atof(equal_ptr));
  1694.             } else if (!stricmp( arg, "matter" )) {
  1695.                 Weapon_info[n].matter = atoi(equal_ptr);
  1696.             } else if (!stricmp( arg, "bounce" )) {
  1697.                 Weapon_info[n].bounce = atoi(equal_ptr);
  1698.             } else if (!stricmp( arg, "speed" )) {
  1699.                 for (i=0; i<NDL-1; i++) {
  1700.                     Weapon_info[n].speed[i] = i2f(atoi(equal_ptr));
  1701.                     equal_ptr = strtok(NULL, space);
  1702.                 }
  1703.                 Weapon_info[n].speed[i] = i2f(atoi(equal_ptr));
  1704.             } else if (!stricmp( arg, "flash_vclip" ))  {
  1705.                 Weapon_info[n].flash_vclip = atoi(equal_ptr);
  1706.             } else if (!stricmp( arg, "flash_sound" ))  {
  1707.                 Weapon_info[n].flash_sound = atoi(equal_ptr);
  1708.             } else if (!stricmp( arg, "flash_size" ))   {
  1709.                 Weapon_info[n].flash_size = fl2f(atof(equal_ptr));
  1710.             } else if (!stricmp( arg, "blob_size" ))    {
  1711.                 Weapon_info[n].blob_size = fl2f(atof(equal_ptr));
  1712.             } else if (!stricmp( arg, "robot_hit_vclip" ))  {
  1713.                 Weapon_info[n].robot_hit_vclip = atoi(equal_ptr);
  1714.             } else if (!stricmp( arg, "robot_hit_sound" ))  {
  1715.                 Weapon_info[n].robot_hit_sound = atoi(equal_ptr);
  1716.             } else if (!stricmp( arg, "wall_hit_vclip" ))   {
  1717.                 Weapon_info[n].wall_hit_vclip = atoi(equal_ptr);
  1718.             } else if (!stricmp( arg, "wall_hit_sound" ))   {
  1719.                 Weapon_info[n].wall_hit_sound = atoi(equal_ptr);
  1720.             } else if (!stricmp( arg, "impact_size" ))  {
  1721.                 Weapon_info[n].impact_size = fl2f(atof(equal_ptr));
  1722.             } else if (!stricmp( arg, "lighted" ))  {
  1723.                 lighted = atoi(equal_ptr);
  1724.             } else if (!stricmp( arg, "lw_ratio" )) {
  1725.                 Weapon_info[n].po_len_to_width_ratio = fl2f(atof(equal_ptr));
  1726.             } else if (!stricmp( arg, "lightcast" ))    {
  1727.                 Weapon_info[n].light = fl2f(atof(equal_ptr));
  1728.             } else if (!stricmp( arg, "persistent" ))   {
  1729.                 Weapon_info[n].persistent = atoi(equal_ptr);
  1730.             } else if (!stricmp(arg, "energy_usage" )) {
  1731.                 Weapon_info[n].energy_usage = fl2f(atof(equal_ptr));
  1732.             } else if (!stricmp(arg, "ammo_usage" )) {
  1733.                 Weapon_info[n].ammo_usage = atoi(equal_ptr);
  1734.             } else if (!stricmp(arg, "fire_wait" )) {
  1735.                 Weapon_info[n].fire_wait = fl2f(atof(equal_ptr));
  1736.             } else if (!stricmp(arg, "fire_count" )) {
  1737.                 Weapon_info[n].fire_count = atoi(equal_ptr);
  1738.             } else if (!stricmp(arg, "damage_radius" )) {
  1739.                 Weapon_info[n].damage_radius = fl2f(atof(equal_ptr));
  1740. //--01/19/95, mk--          } else if (!stricmp(arg, "damage_force" )) {
  1741. //--01/19/95, mk--              Weapon_info[n].damage_force = fl2f(atof(equal_ptr));
  1742.             } else if (!stricmp(arg, "lifetime" )) {
  1743.                 Weapon_info[n].lifetime = fl2f(atof(equal_ptr));
  1744.             } else if (!stricmp(arg, "destroyable" )) {
  1745.                 Weapon_info[n].destroyable = atoi(equal_ptr);
  1746.             } else if (!stricmp(arg, "picture" )) {
  1747.                 Weapon_info[n].picture = bm_load_sub(equal_ptr);
  1748.             } else if (!stricmp(arg, "homing" )) {
  1749.                 Weapon_info[n].homing_flag = !!atoi(equal_ptr);
  1750.             } else {
  1751.                 mprintf( (1, "Invalid parameter, %s=%s in bitmaps.tbl\n", arg, equal_ptr ));
  1752.             }       
  1753.         } else {            // Must be a texture specification...
  1754.             grs_bitmap *bm;
  1755.  
  1756.             bm = load_polymodel_bitmap(arg);
  1757.             if (! lighted)
  1758.                 bm->bm_flags |= BM_FLAG_NO_LIGHTING;
  1759.  
  1760.             lighted = 1;            //default for next bitmap is lighted
  1761.         }
  1762.         arg = strtok( NULL, space );
  1763.     }
  1764.  
  1765.     first_bitmap_num[n_models] = N_ObjBitmapPtrs;
  1766.  
  1767.     for (i=0;i<n_models;i++) {
  1768.         int n_textures;
  1769.         int model_num,last_model_num;
  1770.  
  1771.         n_textures = first_bitmap_num[i+1] - first_bitmap_num[i];
  1772.  
  1773.         model_num = load_polygon_model(model_name[i],n_textures,first_bitmap_num[i],NULL);
  1774.  
  1775.         if (i==0) {
  1776.             Weapon_info[n].render_type = WEAPON_RENDER_POLYMODEL;
  1777.             Weapon_info[n].model_num = model_num;
  1778.         }
  1779.         else
  1780.             Polygon_models[last_model_num].simpler_model = model_num+1;
  1781.  
  1782.         last_model_num = model_num;
  1783.     }
  1784.  
  1785.     if ( pof_file_inner )   {
  1786.         Assert(n_models);
  1787.         Weapon_info[n].model_num_inner = load_polygon_model(pof_file_inner,first_bitmap_num[1]-first_bitmap_num[0],first_bitmap_num[0],NULL);
  1788.     }
  1789.  
  1790.     if ((Weapon_info[n].ammo_usage == 0) && (Weapon_info[n].energy_usage == 0))
  1791.         mprintf((1, "Warning: Weapon %i has ammo and energy usage of 0.\n", n));
  1792.  
  1793. // -- render type of none is now legal --   Assert( Weapon_info[n].render_type != WEAPON_RENDER_NONE );
  1794. }
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800. // ------------------------------------------------------------------------------
  1801. #define DEFAULT_POWERUP_SIZE i2f(3)
  1802.  
  1803. void bm_read_powerup(int unused_flag)
  1804. {
  1805.     int n;
  1806.     char    *equal_ptr;
  1807.  
  1808.     Assert(N_powerup_types < MAX_POWERUP_TYPES);
  1809.  
  1810.     n = N_powerup_types;
  1811.     N_powerup_types++;
  1812.  
  1813.     if (unused_flag) {
  1814.         clear_to_end_of_line();
  1815.         return;
  1816.     }
  1817.  
  1818.     // Initialize powerup array
  1819.     Powerup_info[n].light = F1_0/3;     //  Default lighting value.
  1820.     Powerup_info[n].vclip_num = -1;
  1821.     Powerup_info[n].hit_sound = -1;
  1822.     Powerup_info[n].size = DEFAULT_POWERUP_SIZE;
  1823.     Powerup_names[n][0] = 0;
  1824.  
  1825.     // Process arguments
  1826.     arg = strtok( NULL, space ); 
  1827.  
  1828.     while (arg!=NULL)   {
  1829.         equal_ptr = strchr( arg, '=' );
  1830.         if ( equal_ptr )    {
  1831.             *equal_ptr='\0';
  1832.             equal_ptr++;
  1833.             // if we have john=cool, arg is 'john' and equal_ptr is 'cool'
  1834.             if (!stricmp( arg, "vclip_num" ))   {
  1835.                 Powerup_info[n].vclip_num = atoi(equal_ptr);
  1836.             } else if (!stricmp( arg, "light" ))    {
  1837.                 Powerup_info[n].light = fl2f(atof(equal_ptr));
  1838.             } else if (!stricmp( arg, "hit_sound" ))    {
  1839.                 Powerup_info[n].hit_sound = atoi(equal_ptr);
  1840.             } else if (!stricmp( arg, "name" )) {
  1841.                 Assert(strlen(equal_ptr) < POWERUP_NAME_LENGTH);    //  Oops, name too long.
  1842.                 strcpy(Powerup_names[n], &equal_ptr[1]);
  1843.                 Powerup_names[n][strlen(Powerup_names[n])-1] = 0;
  1844.             } else if (!stricmp( arg, "size" )) {
  1845.                 Powerup_info[n].size = fl2f(atof(equal_ptr));
  1846.             } else {
  1847.                 mprintf( (1, "Invalid parameter, %s=%s in bitmaps.tbl\n", arg, equal_ptr ));
  1848.             }       
  1849.         } else {            // Must be a texture specification...
  1850.             mprintf( (1, "Invalid argument, %s in bitmaps.tbl\n", arg ));
  1851.         }
  1852.         arg = strtok( NULL, space );
  1853.     }
  1854.  
  1855.     ObjType[Num_total_object_types] = OL_POWERUP;
  1856.     ObjId[Num_total_object_types] = n;
  1857.     //printf( "Object type %d is a powerup\n", Num_total_object_types );
  1858.     Num_total_object_types++;
  1859.  
  1860. }
  1861.  
  1862. void bm_read_hostage()  
  1863. {
  1864.     int n;
  1865.     char    *equal_ptr;
  1866.  
  1867.     Assert(N_hostage_types < MAX_HOSTAGE_TYPES);
  1868.  
  1869.     n = N_hostage_types;
  1870.     N_hostage_types++;
  1871.  
  1872.     // Process arguments
  1873.     arg = strtok( NULL, space ); 
  1874.  
  1875.     while (arg!=NULL)   {
  1876.         equal_ptr = strchr( arg, '=' );
  1877.         if ( equal_ptr )    {
  1878.             *equal_ptr='\0';
  1879.             equal_ptr++;
  1880.  
  1881.             if (!stricmp( arg, "vclip_num" ))
  1882.  
  1883.                 Hostage_vclip_num[n] = atoi(equal_ptr);
  1884.  
  1885.             else
  1886.  
  1887.                 mprintf( (1, "Invalid parameter, %s=%s in bitmaps.tbl\n", arg, equal_ptr ));
  1888.  
  1889.         } else
  1890.             mprintf( (1, "Invalid argument, %s in bitmaps.tbl at line %d\n", arg, linenum ));
  1891.  
  1892.         arg = strtok( NULL, space );
  1893.     }
  1894.  
  1895.     ObjType[Num_total_object_types] = OL_HOSTAGE;
  1896.     ObjId[Num_total_object_types] = n;
  1897.     //printf( "Object type %d is a hostage\n", Num_total_object_types );
  1898.     Num_total_object_types++;
  1899.  
  1900. }
  1901.  
  1902.  
  1903. void bm_read_hostage_face() 
  1904. {
  1905.     char *abm_name,*equal_ptr;
  1906.     int clip_num=-1,sound_num=-1;
  1907.     fix time;
  1908.  
  1909.     abm_name = strtok( NULL, space );
  1910.  
  1911.     arg = strtok( NULL, space ); 
  1912.     while (arg!=NULL)   {
  1913.         equal_ptr = strchr( arg, '=' );
  1914.         if ( equal_ptr )    {
  1915.             *equal_ptr='\0';
  1916.             equal_ptr++;
  1917.  
  1918.             // if we have john=cool, arg is 'john' and equal_ptr is 'cool'
  1919.  
  1920.             if (!stricmp( arg, "clip_num" ))    {
  1921.                 clip_num = atoi(equal_ptr);
  1922.             } else if (!stricmp( arg, "time" )) {
  1923.                 time = fl2f(atof(equal_ptr));
  1924.             } else if (!stricmp( arg, "sound_num" ))    {
  1925.                 sound_num = atoi(equal_ptr);
  1926.             }
  1927.         }
  1928.  
  1929.         arg = strtok( NULL, space );
  1930.     }
  1931.  
  1932.  #ifndef SHAREWARE
  1933.  
  1934.     Assert(clip_num>=0 && clip_num<MAX_HOSTAGES);
  1935.  
  1936.     ab_load( abm_name, Hostage_face_clip[clip_num].frames, &Hostage_face_clip[clip_num].num_frames );
  1937.  
  1938.     Assert(Hostage_face_clip[clip_num].num_frames < MAX_BITMAPS_PER_BRUSH);
  1939.  
  1940.     Hostage_face_clip[clip_num].play_time = time;
  1941.     Hostage_face_clip[clip_num].sound_num = sound_num;
  1942.     Hostage_face_clip[clip_num].frame_time = time/Hostage_face_clip[clip_num].num_frames;
  1943.  
  1944.  #endif
  1945. }
  1946.  
  1947. void bm_write_all(FILE *fp)
  1948. {
  1949.     int i;
  1950.  
  1951.     fwrite( &NumTextures, sizeof(int), 1, fp );
  1952.     fwrite( Textures, sizeof(bitmap_index), MAX_TEXTURES, fp );
  1953.     fwrite( TmapInfo, sizeof(tmap_info), MAX_TEXTURES, fp );
  1954.  
  1955.     fwrite( Sounds, sizeof(ubyte), MAX_SOUNDS, fp );
  1956.     fwrite( AltSounds, sizeof(ubyte), MAX_SOUNDS, fp );
  1957.  
  1958.     fwrite( &Num_vclips, sizeof(int), 1, fp );
  1959.     fwrite( Vclip, sizeof(vclip), VCLIP_MAXNUM, fp );
  1960.  
  1961.     fwrite( &Num_effects, sizeof(int), 1, fp );
  1962.     fwrite( Effects, sizeof(eclip), MAX_EFFECTS, fp );
  1963.  
  1964.     fwrite( &Num_wall_anims, sizeof(int), 1, fp );
  1965.     fwrite( WallAnims, sizeof(wclip), MAX_WALL_ANIMS, fp );
  1966.  
  1967.     fwrite( &N_robot_types, sizeof(int), 1, fp );
  1968.     fwrite( Robot_info, sizeof(robot_info), MAX_ROBOT_TYPES, fp );
  1969.  
  1970.     fwrite( &N_robot_joints, sizeof(int), 1, fp );
  1971.     fwrite( Robot_joints, sizeof(jointpos), MAX_ROBOT_JOINTS, fp );
  1972.  
  1973.     fwrite( &N_weapon_types, sizeof(int), 1, fp );
  1974.     fwrite( Weapon_info, sizeof(weapon_info), MAX_WEAPON_TYPES, fp );
  1975.  
  1976.     fwrite( &N_powerup_types, sizeof(int), 1, fp );
  1977.     fwrite( Powerup_info, sizeof(powerup_type_info), MAX_POWERUP_TYPES, fp );
  1978.     
  1979.     fwrite( &N_polygon_models, sizeof(int), 1, fp );
  1980.     fwrite( Polygon_models, sizeof(polymodel), N_polygon_models, fp );
  1981.  
  1982.     for (i=0; i<N_polygon_models; i++ ) {
  1983.         fwrite( Polygon_models[i].model_data, sizeof(ubyte), Polygon_models[i].model_data_size, fp );
  1984.     }
  1985.  
  1986.     fwrite( Gauges, sizeof(bitmap_index), MAX_GAUGE_BMS, fp );
  1987.  
  1988.     fwrite( Dying_modelnums, sizeof(int), MAX_POLYGON_MODELS, fp );
  1989.     fwrite( Dead_modelnums, sizeof(int), MAX_POLYGON_MODELS, fp );
  1990.  
  1991.     fwrite( ObjBitmaps, sizeof(bitmap_index), MAX_OBJ_BITMAPS, fp );
  1992.     fwrite( ObjBitmapPtrs, sizeof(ushort), MAX_OBJ_BITMAPS, fp );
  1993.  
  1994.     fwrite( &only_player_ship, sizeof(player_ship), 1, fp );
  1995.  
  1996.     fwrite( &Num_cockpits, sizeof(int), 1, fp );
  1997.     fwrite( cockpit_bitmap, sizeof(bitmap_index), N_COCKPIT_BITMAPS, fp );
  1998.  
  1999.     fwrite( Sounds, sizeof(ubyte), MAX_SOUNDS, fp );
  2000.     fwrite( AltSounds, sizeof(ubyte), MAX_SOUNDS, fp );
  2001.  
  2002.     fwrite( &Num_total_object_types, sizeof(int), 1, fp );
  2003.     fwrite( ObjType, sizeof(byte), MAX_OBJTYPE, fp );
  2004.     fwrite( ObjId, sizeof(byte), MAX_OBJTYPE, fp );
  2005.     fwrite( ObjStrength, sizeof(fix), MAX_OBJTYPE, fp );
  2006.  
  2007.     fwrite( &First_multi_bitmap_num, sizeof(int), 1, fp );
  2008.  
  2009.     fwrite( &N_controlcen_guns, sizeof(int), 1, fp );
  2010.     fwrite( controlcen_gun_points, sizeof(vms_vector), MAX_CONTROLCEN_GUNS, fp );
  2011.     fwrite( controlcen_gun_dirs, sizeof(vms_vector), MAX_CONTROLCEN_GUNS, fp );
  2012.     fwrite( &exit_modelnum, sizeof(int), 1, fp );
  2013.     fwrite( &destroyed_exit_modelnum, sizeof(int), 1, fp );
  2014. }
  2015.  
  2016. #endif
  2017.